package modeladesktop.gui;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import modeladesktop.algoritmo.*;
import org.apache.commons.math.stat.inference.*;
import org.apache.commons.math.*;
import org.apache.commons.math.stat.StatUtils;

public class PanelTabla extends JPanel implements ActionListener{
	private ModeloData modeloDatos = null;
	private JTable datotes;
	private JButton add = new JButton("Agregar Fila");
	private JButton rmv = new JButton("Eliminar Fila");
	private JButton addVar = new JButton("Agregar Variable");
	private JButton rmvVar = new JButton("Eliminar Variable");
	private JButton analizar = new JButton("Analizar Datos");
	private DefaultListModel selecMod = new DefaultListModel();
	private DefaultListModel noSelecMod = new DefaultListModel();
	private JLabel aceptableL = new JLabel("<html>Ingrese numero de correlacion </br> aceptable numero entre 1 y 100</html>");
	private JTextField aceptableTF = new JTextField();

	private JLabel cualL = new JLabel("Variable dependiente");
	private JLabel selecL = new JLabel("Seleccionados");
	private JLabel noSelecL = new JLabel("No seleccionados");
	private JComboBox cual = null;
	private JList selecList = new JList(selecMod);
	private JList noSelecList = new JList(noSelecMod);
	private Object[] cabeceras;

	public PanelTabla(Object [] cabeceras, ArrayList <ArrayList <Double>> data){
		this(cabeceras);
		modeloDatos.setDatos(data);
	}

	public PanelTabla(Object [] cabeceras){
		this.cabeceras = cabeceras;
		setLayout(null);
		cual = new JComboBox(cabeceras);
		modeloDatos = new ModeloData(cabeceras);
		datotes = new JTable(modeloDatos);
		JScrollPane scroll = new JScrollPane(datotes);
		JScrollPane choos = new JScrollPane(selecList);
		JScrollPane desca = new JScrollPane(noSelecList);

		scroll.setBounds(20, 20, 400, 200);
		cualL.setBounds(430, 20, 200, 20);
		cual.setBounds(430, 45, 150, 20);
		add.setBounds(430, 90, 140, 25);
		rmv.setBounds(430, 120, 140, 25);
		selecL.setBounds(20, 230, 150, 20);
		noSelecL.setBounds(220, 230, 150, 20);
		choos.setBounds(20, 250, 200, 100);
		desca.setBounds(220, 250, 200, 100);
		addVar.setBounds(430, 250, 140, 25);
		rmvVar.setBounds(430, 280, 140, 25);
		analizar.setBounds(430, 310, 140, 25);
		aceptableL.setBounds(20, 370, 300, 40);
		aceptableTF.setBounds(20, 410, 100, 30);

		add(scroll);
		add(cualL);
		add(cual);
		add(add);
		add(rmv);
		add(selecL);
		add(noSelecL);
		add(choos);
		add(desca);
		add(addVar);
		add(rmvVar);
		add(analizar);
		add(aceptableL);
		add(aceptableTF);

		add.addActionListener(this);
		rmv.addActionListener(this);
		addVar.addActionListener(this);
		rmvVar.addActionListener(this);
		analizar.addActionListener(this);

		for(Object var : cabeceras)
			noSelecMod.addElement(var);
	}

	private boolean hayDependiente(){
		Object items[] = selecMod.toArray();
		for(Object item: items)
			if(item.toString().equals(cual.getSelectedItem().toString()))
				return true;
		return false;
	}

	public void actionPerformed(ActionEvent ev){
		if(ev.getSource() == add)
			modeloDatos.addRow();
		else if(ev.getSource() == rmv){
			if(datotes.getSelectedRow() != -1)
				modeloDatos.removeRow(datotes.getSelectedRow());
		} else if(ev.getSource() == addVar){
			if(noSelecList.getSelectedIndex() != -1)
				selecMod.addElement(noSelecMod.remove(noSelecList.getSelectedIndex()));
		} else if(ev.getSource() == rmvVar){
			if(selecList.getSelectedIndex() != -1)
				noSelecMod.addElement(selecMod.remove(selecList.getSelectedIndex()));
		} else if(ev.getSource() == analizar) {
			Analisis analizado = new Analisis();
			if(modeloDatos.getRowCount() == 0)
				JOptionPane.showMessageDialog(this, "No hay datos ingresados en la tabla", "Error", JOptionPane.ERROR_MESSAGE);
			else if(modeloDatos.hasNullValues())
				JOptionPane.showMessageDialog(this, "Existen campos sin datos, corriga o eliminelos", "Error", JOptionPane.ERROR_MESSAGE);
			else if(modeloDatos.getRowCount() <= selecMod.getSize()+1)
				JOptionPane.showMessageDialog(this, "No puede tener menos o la misma cantidad de observaciones que la de variables independientes", "Error", JOptionPane.ERROR_MESSAGE);
			else if(selecMod.getSize() == 0)
				JOptionPane.showMessageDialog(this, "Debe tener al menos una variable independiente", "Error", JOptionPane.ERROR_MESSAGE);
			else if(hayDependiente())
				JOptionPane.showMessageDialog(this, "La variable dependiente no puede estar con las independientes", "Error", JOptionPane.ERROR_MESSAGE);
			else {
				double xy[][] = null;
				double indepen [][] = null;
				double depen [] = null;
				if(selecMod.toArray().length == 1){
					xy = modeloDatos.getXYForRegresionSimple(selecMod.toArray()[0], cual.getSelectedItem());
					Regresion.calcRegSimple(analizado, xy);
				} else {
					indepen = modeloDatos.getIndependientes(selecMod.toArray());
					depen = modeloDatos.getDependiente(cual.getSelectedItem());
					Regresion.calcRegMultiple(analizado, depen, indepen);
					Coeficientes.getFiv(modeloDatos.getXsY(selecMod.toArray(), cual.getSelectedItem()), analizado);
					Coeficientes.valoresP(modeloDatos.getXsY(selecMod.toArray(), cual.getSelectedItem()), analizado);
					analizado.matrizCorrelacion = Coeficientes.matCorrelacion(indepen);
					analizado.coefDeterminacion = Regresion.coefDet(modeloDatos.getXsY(selecMod.toArray(), cual.getSelectedItem()));
					analizado.errorEstandarEstimacion = Regresion.coefCorr(modeloDatos.getXsY(selecMod.toArray(), cual.getSelectedItem()));
					analizado.dependiente = cual.getSelectedItem();
				}
				/*ArrayList <double[]> anovaData = modeloDatos.paraANOVA(selecMod.toArray());
				try{
					analizado.anovaF = TestUtils.oneWayAnovaFValue(anovaData);
					analizado.anovaP = TestUtils.oneWayAnovaPValue(anovaData);
				}catch(MathException ex){
					ex.printStackTrace();
				}*/
				//agregado desviaciones y otros parametros para anova darn1986
				double mean = StatUtils.mean(depen);
	               Desviation.calcTotal(analizado, depen, analizado.depPredecida, mean);
	               Desviation.calcExplicada(analizado, depen, analizado.depPredecida, mean);
	               Desviation.calcNoExplicada(analizado, depen, analizado.depPredecida);
				if(indepen[0].length==2){
					Anov an=new Anov(analizado, indepen);
					an.calc(analizado);
				}

               	//fin de la modificacion 
					
				analizado.nombreCoeficientesEcuacion = selecMod.toArray();
				this.imprimir(analizado,indepen, depen, analizado.depPredecida,analizado.desviacionTotal, analizado.desviacionExplicada, analizado.desviacionNoExplicada,analizado.anova);
					
				JTabbedPane principal = (JTabbedPane)getParent();
				Object cosos [] = selecMod.toArray();
				Object variables[] = new Object[cosos.length + 1];
				variables[0] = "constante";
				for(int ix = 0; ix < cosos.length; ix++)
					variables[ix+1] = cosos[ix];
				principal.add("Tabla de coeficientes", new PanelAnalisis(variables, analizado));
			}
		}
	}
	/*agregado metodo para imprimir y probar lo actual*/
	public void imprimir(Analisis analizado,double indepen[][],double depen[],double depenPredecida[],double desvTotal[],double desvExplicada[],double desvNoExplicada[],double[][] anova){

        for(int i=0;i<depen.length;i++)
        {
            //imprimir variables independientes
            for(int j=1;j<indepen[i].length;j++){
                System.out.print(""+indepen[i][j]+",");
                System.out.print((j<indepen[i].length-1)?",":"");
            }

            System.out.println(","+depen[i]+","+depenPredecida[i]+","+desvTotal[i]+","+desvExplicada[i]+","+desvNoExplicada[i]);
        }

        System.out.println("Sct "+analizado.sct+" Scr "+analizado.scr+" Sce "+analizado.sce);
        //System.out.println("Scx "+analizado.scx+" Scm "+analizado.scm+" Se "+analizado.se+" Sb1 "+analizado.sb1+" Cme "+analizado.cme);
        System.out.println("N "+analizado.N);
        System.out.println("K "+analizado.K);

        System.out.println("Matriz de Anova");
        if(indepen[0].length==2){
            for(int i=0;i<anova.length;i++)
            {
                for(int j=0;j<anova[i].length;j++){
                    System.out.println(""+i+","+j+" "+anova[i][j]);
                }
            }
        }


    }
	/*fin*/
}
